package net.entelijan.cobean.notification;

import java.beans.PropertyChangeEvent;
import java.util.ArrayList;
import java.util.List;

import net.entelijan.cobean.core.ICobean;
import net.entelijan.cobean.core.impl.INamedPropertyChangeListener;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * A property change listener that records every event it gets. Can be used in
 * testcases to ensure that components fire their events as expected.
 * 
 */
public class RecordingPropertyChangeListener implements INamedPropertyChangeListener {

	private static Log log = LogFactory
			.getLog(RecordingPropertyChangeListener.class);

	private List<EventContentBean> eventContents = new ArrayList<EventContentBean>();

	/**
	 * Defines the property that should be observed. If null all properties are observed
	 */
	private String propertyName;

	public RecordingPropertyChangeListener(String propertyName) {
		super();
		this.propertyName = propertyName;
	}

	@Override
	public void propertyChange(PropertyChangeEvent evt) {
		final String propertyName = evt.getPropertyName();
		if (this.propertyName == null || this.propertyName.equals(propertyName)) {
			Object newValue = evt.getNewValue();
			Object oldValue = evt.getOldValue();
			ICobean<?> src = (ICobean<?>) evt.getSource();
			log.debug("[propertyChange] propertyName:" + propertyName
					+ " value:'" + oldValue + "'->'" + newValue + "'" + " src:"
					+ src);
			eventContents.add(new EventContentBean(oldValue, newValue,
					propertyName));
		}
	}

	@Override
	public String toString() {
		return ToStringBuilder.reflectionToString(this,
				ToStringStyle.SHORT_PREFIX_STYLE);
	}

	public int getNotificationCount() {
		return eventContents.size();
	}

	public void resetNotificationCount() {
		this.eventContents = new ArrayList<EventContentBean>();
	}

	public List<EventContentBean> getEventContents() {
		return eventContents;
	}

	@Override
	public String getName() {
		return this.propertyName;
	}

}
